import java.util.Random;


public class Chromosome {
	public int [] data;
	public long timeInPrison;
	public int gamesWon;
	public int gamesPlayed;
	public int score;
	
	
	public Chromosome(boolean randomize){
		
		data = new  int [Data.chromozomSize];
		timeInPrison = 0;
		gamesWon = 0;
		gamesPlayed = 0;
		score = 0;
		
		if(randomize){
			for(int i=0; i< data.length ; i++)
				data[i] =  Data.ChromoCreationRandomGenerator.nextInt(2);
		}
		else{
			for(int i=0; i< data.length ; i++)
				data[i] =  0;
		}
	}
	
	public Chromosome(Chromosome old){
		
		data = new int [old.data.length];
		for(int i = 0; i < old.data.length ;i++ )
			data[i]=old.data[i];
		timeInPrison = 0;
		gamesWon = 0;
		gamesPlayed = 0;
	}
	
	public Chromosome(int[] arr){
		
		data = new int [arr.length];
		for(int i = 0; i < arr.length ;i++ )
			data[i]=arr[i];
		timeInPrison = 0;
		gamesWon = 0;
		gamesPlayed = 0;
	}

	
	public void mutate(){
		for(int i=0 ; i < data.length  ; i++ ){
			if (Data.mutationRandomGenerator.nextDouble() < Data.bitMutateProbability){
				data[i]=1-data[i];
			}
			
		}
			
	}
	public void play (Chromosome opponent){
		
		int [] myPreviousSteps = new int[Data.memory * 2];
		int [] opponentPreviousSteps = new int[Data.memory * 2];
		
		// initialize previous steps . ( from data)
		int i=(Data.chromozomSize-2*Data.memory) , j=0;
		for( ; i < Data.chromozomSize ; i++){
			myPreviousSteps[j] = data [i];
			opponentPreviousSteps[j] = opponent.data[i];
			j++;
		}
		
		// play the game
		int myTotalScore=0 , oppTotalScore =0;
		int myChoice,oppChoice;
		for(i=0 ; i < Data.gameLength ; i++){
			
			//get our decisions
			myChoice= data[getIndex(myPreviousSteps)];
			oppChoice= opponent.data[getIndex(opponentPreviousSteps)];
			
			//set score
			if(myChoice==0 && oppChoice == 0){
				myTotalScore+=1;
				oppTotalScore+=1;
			}
			else if(myChoice==0 && oppChoice == 1){
				myTotalScore+=5;
			}
			else if(myChoice==1 && oppChoice == 0){
				oppTotalScore+=5;			
			}
			else if(myChoice==1 && oppChoice == 1){
				myTotalScore+=3;
				oppTotalScore+=3;
			}
			
			//set previous steps
				//shift 
			for(j=2; j<myPreviousSteps.length;j++){
				myPreviousSteps[j-2]=myPreviousSteps[j];
				opponentPreviousSteps[j-2]=opponentPreviousSteps[j];
			}
				//set the new choices
			myPreviousSteps[j-2]=myChoice;
			myPreviousSteps[j-1]=oppChoice;
			opponentPreviousSteps[j-2]=oppChoice;
			opponentPreviousSteps[j-1]=myChoice;
		}
		
		//set the results of the game
		timeInPrison+=myTotalScore;
		gamesPlayed++;
		if(myTotalScore <= oppTotalScore)
			gamesWon++;
	}
	
	private static int getIndex(int [] arr){
		int result=0;
		int length = arr.length - 1;
		int fac=1;
		while (length > 0){
			result+=fac*arr[length];
			length--;
			fac*=2;
		}
		return result;
	}
	
	public static Chromosome[] crossOver(Chromosome a, Chromosome b){
		
		Random r;
		Chromosome[] result= new Chromosome[2];
		//create empty chromosomes
		result[0]=new Chromosome(false);
		result[1]=new Chromosome(false);
		
		switch(Data.crossOverMethod) { 
			case ByBitCrossOver :
				r= new Random(Data.crossOverRandomGenerator.nextInt());
				for(int i=0 ; i < Data.chromozomSize ; i++){
					if(r.nextBoolean()){
						result[0].data[i]=a.data[i];
						result[1].data[i]=b.data[i];
					}
					else{
						result[0].data[i]=b.data[i];
						result[1].data[i]=a.data[i];
					}
				}
			break;
			
			case RandomPointCrossOver :
				r= new Random(Data.crossOverRandomGenerator.nextInt());
				int breakPoint = r.nextInt(Data.chromozomSize);
				for(int i = 0 ; i < breakPoint ; i++ ){
					result[0].data[i]=a.data[i];
					result[1].data[i]=b.data[i];
				}
				for(int i = breakPoint ; i < Data.chromozomSize ; i++ ){
					result[0].data[i]=b.data[i];
					result[1].data[i]=a.data[i];
				}
			break;
			
			case M_PartsCrossOver :
				
			break;
				
		}
		
		result[0].mutate();
		result[1].mutate();
		return result;
	}
}
